package modules.exports;

import core.Duree;
import core.GroupeNotes;
import core.Mesure;
import core.Note;
import core.Partition;
import core.Section;
import core.Tools;



public class ExportLilyPond {

	/**
	 * @param args
	 * 
	 * Conventions de nomages :
	 * 
	 * Grosse Caisse : 			ré3 
	 * Caisse Claire :			si3
	 * Charlestone :			sol4 
	 * Charlestone (au pied):	ré3 (x)
	 * Ride :					la4 (x) Pour la différencier
	 * Crash :					la4 (un rond avec une croix dedans) 
	 * Tom aigu :				mi4
	 * Tom medium :				ré4
	 * Tom basse :				fa3
	 * 
	 * valeurs des figures (En 4 temps la durée de la mesure est 384) :
	 * 
	 * ronde ou pause : 					384 
	 * blanche ou demie-pause : 			192 
	 * noire ou soupir : 					96
	 * croche ou demi-soupir : 				48
	 * double-croche ou quart de soupir :	24
	 * triple-croche ou huitième de soupir:	12
	 * 
	 * Pointées :
	 * 
	 * blanche : 			192+96=	288
	 * noire :				96+48 =	144 	
	 * croche :				48+24 = 72
	 * double-croche :		24+12 =	36
	 * 
	 * triolets :
	 * 
	 * blanche :		64
	 * noire : 			32
	 * croche :			16
	 * double-croche :	8
	 * ...
	 * 
	 * 
	 */
	//private static String commandeLily = "/home/user/lilypond/usr/bin/lilypond";
	//private static String commandeLily = "lilypond";
	private static String commandeLily = "lilypond";
	
	private static String convertirTemps(double duree) {
		if(duree == Duree.BLANCHE_POINTEE){return "2.";}
		if(duree == Duree.NOIRE_POINTEE){return "4.";} //SOUPIR_POINTE
		if(duree == Duree.CROCHE_POINTEE){return "8.";}  //DEMI_SOUPIR_POINTE
		if(duree == Duree.DOUBLE_CROCHE_POINTEE){return "16.";} //QUART_DE_SOUPIR_POINTE
		else {
			return String.valueOf((int)(384/duree));	
		}
	}
	
	private static String convertirNom(String label) {
		if(label =="Caisse Claire")label="snare";
		if(label =="Caisse Claire Baguette")label="sidestick"; //rim-shot
		
		if(label =="Grosse Caisse")label="bassdrum";
		
		
		/* liste des toms :
		 * hightom	
		 * himidtom 
		 * lowmidtom 
		 * lowtom 
		 * highfloortom 
		 * lowfloortom  
		*/
		if(label =="Tom 1")label="hightom"; //himidtom
		if(label =="Tom 2")label="lowtom";
		if(label =="Tom Basse")label="lowfloortom";
		
		if(label =="Charley")label="hihat";
		if(label =="Charley ferme")label="closedhihat";
		if(label =="Charley semi ouvert")label="halfopenhihat";
		if(label =="Charley ouvert")label="openhihat";
		if(label =="Charley pied")label="pedalhihat";
		
		if(label =="Ride Bell")label="ridebell";
		if(label =="Ride Side")label="ridecymbal";
		if(label =="Ride Side Strong")label="ridecymbal";//temporaire
		
		if(label =="Crash 1 Bell")label="crashcymbal";//temporaire
		if(label =="Crash 1")label="crashcymbal";
		if(label =="Crash 1 Strong")label="crashcymbal";//temporaire
		if(label =="Crash 2 Bell")label="crashcymbalb";//temporaire
		if(label =="Crash 2")label="crashcymbalb"; // temporaire
		if(label =="Crash 2 Strong")label="crashcymbalb"; // temporaire
		
		if(label =="Splash")label="splashcymbal";
		
		// Autres instruments possibles
		if(label =="Cymbale Chinoise")label="chinesecymbal";
		if(label =="Tambourin")label="tambourine";
	    if(label =="Cloche")label="cowbell";
		
		
		
		if(label =="Silence")label="r";
		
		return label;	
	}
	
	public static void exporter(Partition partition, String emplacementFichierExport){
		
		String voieHaute = "";
		String voieBasse = "";
		
		int numeroSection = 1;
		for(Section section : partition.getSection()){
			int numeroMesure = 1;
			String nomSection = section.getName();
			voieHaute+="% section : "+numeroSection+", nom : "+nomSection+"\n" ;
			voieBasse+="% section : "+numeroSection+", nom : "+nomSection+"\n \\mark \\markup { \\bold {"+nomSection+"} } \n";
			for(Mesure mesure : section.getMesure()){
				for(GroupeNotes groupeNotes : mesure.getGroupeNote()){
					
					String dureeGroupe = convertirTemps(groupeNotes.getDuree());
					double voieGroupe = groupeNotes.getVoie();
					String notesDuGroupe ="";
					
					for(Note note : groupeNotes.getNotes()){
						String labelNote = note.getcode();
						
						if(groupeNotes.getNotes().size()>1){
							notesDuGroupe += labelNote+" ";
						}
						else{
							notesDuGroupe += labelNote+dureeGroupe;
						}
					}
					
					if(groupeNotes.getNotes().size()>1)notesDuGroupe = "<"+notesDuGroupe+">"+dureeGroupe;
					if(voieGroupe==1)voieHaute+=notesDuGroupe+" ";
					if(voieGroupe==2)voieBasse+=notesDuGroupe+" ";
				}
				voieHaute+=" % mesure : "+numeroMesure+"\n" ;
				voieBasse+=" % mesure : "+numeroMesure+"\n";
				numeroMesure++;
			}
			//voieHaute+="\\break";
			//voieBasse+="\\break";
			numeroSection++;
		}
		
		int tempo = Math.round(Math.round(partition.getTempo()*2.042007001));
		
		String top = "\\include \"StyleBatterie.ly\" \n"+
		"#(ly:set-option 'delete-intermediate-files #t)\n"+

		"\\paper {\n"+
			"\tbetween-system-padding = #6\n"+
		"}\n";
		String header = 
		"\\header {\n"+
			"\ttitle = \\markup { \\column  { \\left-align { \\fontsize #2  \\bold \""+partition.getTitre()+"\"  } } }\n"+
			"\tsubtitle = \\markup { \\column  { \\left-align { \\fontsize #1  \\bold \""+partition.getSousTitre()+"\"  } } }\n"+
			"\tcomposer = \\markup { \\column  { \\left-align { \\fontsize #1  \\bold \""+partition.getAuteur()+"\"  } } }\n"+
			//"\tinstrument = \\markup { \\column  { \\left-align { \\fontsize #1  \\bold \""+partition.getInstrument()+"\"  } } }\n"+
		"}\n\n";
		String up = 	
		"up = \\repeat volta 2 \n"+
			"\t\\drummode {\n"+
				"\t\t\\repeat unfold 1 {\n"+
				//"	cymra8 cymra8 cymra8 cymra8 cymra8 cymra8 cymra8 cymra8 \n"+
				voieHaute+"\n"+
				"\t\t\\break" +
				"\t\t\\bar  \":|\" \n"+
		"		\t\t}\n"+
			"\t}\n";
		String down = 
		"down = \\repeat volta 2 \n"+
		"	\t\\drummode{\n"+
		"		\t\t\\repeat unfold 1 {\n"+
		//"			bd4 sn bd8 bd sn bd \n"+
				voieBasse+"\n"+
		"		\t\t\\break\n"+ 
		"		\t\t\\bar  \":|\"\n"+
		"		\t\t}\n"+
		"	\t}\n\n";
		String score = 
		"\\score {\n"+
		"<<\n"+
		"	\t\\tempo 4 = "+tempo+"\n"+
		"	\t\\override Score.DynamicText #'transparent = ##t\n"+
		"	\t\\override Score.BarNumber #'font-size = #2\n"+
		"	\t\\override Score.BarNumber #'stencil = #(make-stencil-circler 0.1 0.25 ly:text-interface::print)\n\n"+
		"	\t\\new DrumStaff \n"+
		"	\t\\with {\n"+
		"		\t\tdrumStyleTable =  #(alist->hash-table mydrums-style2)\n"+
		"		\t\t\\override DrumStaff #'TimeSignature #'style = #'() fontSize = #1\n"+
		"        \t\t\\override StaffSymbol #'staff-space = #(magstep 1)\n"+
		"	\t}\n"+
		"	\t<<\n"+
		"	\t\\set Staff.instrumentName = \""+partition.getInstrument()+"\"\n"+
		"	\t\\override Score.MetronomeMark #'extra-offset = #'(-10 . 1.5)\n"+
		"    \t\t\\new DrumVoice { \\voiceOne \\up }\n"+
		"    \t\t\\new DrumVoice { \\voiceTwo \\down }\n"+
		"     \t>>\n"+
		">>\n\n";
		String layout = 
		"\\layout {\n"+
		"	\t\\context {\n"+
		"	   \t\t\\RemoveEmptyStaffContext\n"+
		"	   \t\t\\override VerticalAxisGroup #'remove-first = ##t\n"+
		"	\t}\n"+
		"}\n\n";
		String midi = 
		"\\midi {\n"+
		"	\t\\context {\n"+
		"	\t\\Score\n"+
		"      \t\ttempoWholesPerMinute = #(ly:make-moment "+tempo+" 4)\n"+
		"	\t}\n"+
		"}\n";
		String foot ="}";

	
		String contenuExport = top+header+up+down+score+layout+midi+foot;
		
		Tools.ecrireFichier(emplacementFichierExport+".ly", contenuExport);
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
	    try {
	    	System.out.println("Commande : "+commandeLily +
	    			" -o "+emplacementFichierExport+" "+
	    			emplacementFichierExport+".ly");
	    	
	    	Process processus = Runtime.getRuntime().exec(commandeLily+
	    			" -o "+emplacementFichierExport+" "+
	    			emplacementFichierExport+".ly");
	    	
	    	//System.out.println(" trace : "+processus.getOutputStream());
	    	new LogStreamReader(processus.getInputStream()).start();
	    	new LogStreamReader(processus.getErrorStream()).start();
	    	processus.waitFor();
	        int exitVal = processus.exitValue();
	        System.out.println("Commande terminée : exit value = "+exitVal ); 

	    } catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}		
}